package com.dge.common.widgets.progressbar

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.RectF
import android.graphics.Shader
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import android.widget.ProgressBar
import com.dge.common.R
import com.dge.common.extentions.dp

class ArcProgress @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    ProgressBar(context, attrs, defStyleAttr) {
    private val DEFAULT_LINEHEIGHT = dp2px(15)
    private val DEFAULT_mTickWidth = dp2px(2)
    private val DEFAULT_mRadius = dp2px(72)
    private val DEFAULT_mUnmProgressColor = -0x151516
    private val DEFAULT_mProgressColor = Color.YELLOW
    private val DEFAULT_OFFSETDEGREE = 60
    private val DEFAULT_DENSITY = 4
    private val MIN_DENSITY = 2
    private val MAX_DENSITY = 8
    private var mStylePogress = STYLE_TICK
    private val mBgShow: Boolean
    private val mRadius: Float
    private val mArcbgColor: Int
    private val mBoardWidth: Int
    private var mDegree = DEFAULT_OFFSETDEGREE
    private var mArcRectf: RectF? = null
    private val mLinePaint: Paint
    private val mArcPaint: Paint
    private val mArcUnReachedPaint: Paint
    private val shadowPaint: Paint? = null
    private val mUnmProgressColor: Int
    private val mProgressColor: Int
    private val mTickWidth: Int
    private var mTickDensity: Int
    private var mCenterBitmap: Bitmap? = null
    private var mCenterCanvas: Canvas? = null
    private var mOnCenter: OnCenterDraw? = null

    init {
        val attributes = getContext().obtainStyledAttributes(
            attrs, R.styleable.ArcProgress
        )
        mBoardWidth = attributes.getDimensionPixelOffset(R.styleable.ArcProgress_arc_borderWidth, DEFAULT_LINEHEIGHT)
        mUnmProgressColor = attributes.getColor(R.styleable.ArcProgress_arc_unprogresColor, DEFAULT_mUnmProgressColor)
        mProgressColor = attributes.getColor(R.styleable.ArcProgress_arc_pgColor, DEFAULT_mProgressColor)
        mTickWidth = attributes.getDimensionPixelOffset(R.styleable.ArcProgress_arc_tickWidth, DEFAULT_mTickWidth)
        mTickDensity = attributes.getInt(R.styleable.ArcProgress_arc_tickDensity, DEFAULT_DENSITY)
        mRadius = attributes.getDimensionPixelOffset(R.styleable.ArcProgress_arc_radius, DEFAULT_mRadius).toFloat()
        mArcbgColor = attributes.getColor(R.styleable.ArcProgress_arc_bgColor, DEFAULT_mUnmProgressColor)
        mTickDensity = Math.max(Math.min(mTickDensity, MAX_DENSITY), MIN_DENSITY)
        mBgShow = attributes.getBoolean(R.styleable.ArcProgress_arc_bgShow, false)
        mDegree = attributes.getInt(R.styleable.ArcProgress_arc_degree, DEFAULT_OFFSETDEGREE)
        mStylePogress = attributes.getInt(R.styleable.ArcProgress_arc_progressStyle, STYLE_TICK)
        val capRount = attributes.getBoolean(R.styleable.ArcProgress_arc_capRound, false)
        mArcPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mArcPaint.color = mArcbgColor
        if (capRount) mArcPaint.strokeCap = Paint.Cap.ROUND
        mArcPaint.strokeWidth = mBoardWidth.toFloat()
        mArcPaint.style = Paint.Style.STROKE
        mArcPaint.isAntiAlias = true
        mArcPaint.isDither = true
        mArcPaint.setShadowLayer(6f.dp, 0f, 2f, Color.parseColor("#5A1C5BFF"))

        mArcUnReachedPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mArcUnReachedPaint.color = mArcbgColor
        if (capRount) mArcUnReachedPaint.strokeCap = Paint.Cap.ROUND
        mArcUnReachedPaint.strokeWidth = mBoardWidth.toFloat()
        mArcUnReachedPaint.style = Paint.Style.STROKE
        mLinePaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mLinePaint.strokeWidth = mTickWidth.toFloat()
    }

    fun setOnCenterDraw(mOnCenter: OnCenterDraw?) {
        this.mOnCenter = mOnCenter
    }

    @Synchronized
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var widthMeasureSpec = widthMeasureSpec
        var heightMeasureSpec = heightMeasureSpec
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        if (widthMode != MeasureSpec.EXACTLY) {
            val widthSize = (mRadius * 2 + mBoardWidth * 2).toInt()
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY)
        }
        if (heightMode != MeasureSpec.EXACTLY) {
            val heightSize = (mRadius * 2 + mBoardWidth * 2).toInt()
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY)
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    @Synchronized
    override fun onDraw(canvas: Canvas) {
        canvas.save()
        val roate = progress * 1.0f / max
        val x = mArcRectf!!.right / 2 + mBoardWidth / 2
        val y = mArcRectf!!.right / 2 + mBoardWidth / 2
        if (mOnCenter != null) {
            if (mCenterCanvas == null) {
                mCenterBitmap = Bitmap.createBitmap(mRadius.toInt() * 2, mRadius.toInt() * 2, Bitmap.Config.ARGB_8888)
                mCenterCanvas = Canvas(mCenterBitmap!!)
            }
            mCenterCanvas!!.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
            mOnCenter!!.draw(mCenterCanvas, mArcRectf, x, y, mBoardWidth.toFloat(), progress)
            canvas.drawBitmap(mCenterBitmap!!, 0f, 0f, null)
        }
        val angle = mDegree / 2
        val count = (360 - mDegree) / mTickDensity
        val target = (roate * count).toInt()
        if (mStylePogress == STYLE_ARC) {
            val targetDegree = (360 - mDegree) * roate
            //绘制未完成部分
            mArcUnReachedPaint.color = mUnmProgressColor
            canvas.drawArc(mArcRectf!!, 90 + angle + targetDegree, 360 - mDegree - targetDegree, false, mArcUnReachedPaint)
            //绘制完成部分
            mArcPaint.color = mProgressColor
            // 创建一个线性渐变色
            val startColor = Color.parseColor("#68A2FF")
            val endColor = Color.parseColor("#1453F8")
            val shader: Shader = LinearGradient(0f, 0f, 0f, height * 1f, startColor, endColor, Shader.TileMode.CLAMP)
            mArcPaint.shader = shader// 将渐变色设置到Paint对象中
            canvas.drawArc(mArcRectf!!, (90 + angle).toFloat(), targetDegree, false, mArcPaint)
        } else {
            if (mBgShow) canvas.drawArc(mArcRectf!!, (90 + angle).toFloat(), (360 - mDegree).toFloat(), false, mArcPaint)
            canvas.rotate((180 + angle).toFloat(), x, y)
            for (i in 0 until count) {
                if (i < target) {
                    mLinePaint.color = mProgressColor
                } else {
                    mLinePaint.color = mUnmProgressColor
                }
                canvas.drawLine(
                    x,
                    (mBoardWidth + mBoardWidth / 2).toFloat(),
                    x,
                    (mBoardWidth - mBoardWidth / 2).toFloat(),
                    mLinePaint
                )
                canvas.rotate(mTickDensity.toFloat(), x, y)
            }
        }
        canvas.restore()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mArcRectf = RectF(
            mBoardWidth.toFloat(),
            mBoardWidth.toFloat(),
            mRadius * 2 - mBoardWidth,
            mRadius * 2 - mBoardWidth
        )
        Log.e("DEMO", "right == " + mArcRectf!!.right + "   mRadius == " + mRadius * 2)
    }

    /**
     * dp 2 px
     *
     * @param dpVal
     */
    protected fun dp2px(dpVal: Int): Int {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dpVal.toFloat(), resources.displayMetrics
        ).toInt()
    }

    interface OnCenterDraw {
        /**
         * @param canvas
         * @param rectF       圆弧的Rect
         * @param x           圆弧的中心x
         * @param y           圆弧的中心y
         * @param storkeWidth 圆弧的边框宽度
         * @param progress    当前进度
         */
        fun draw(canvas: Canvas?, rectF: RectF?, x: Float, y: Float, storkeWidth: Float, progress: Int)
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        if (mCenterBitmap != null) {
            mCenterBitmap!!.recycle()
            mCenterBitmap = null
        }
    }

    companion object {
        const val STYLE_TICK = 1
        const val STYLE_ARC = 0
    }
}